#include "slave.h"

#define remote_ldm(coreid,ldm_var) ((unsigned long)&ldm_var | ((unsigned long)coreid << 20 ) |(1ULL << 45))

extern volatile int main_test;
__thread_local_fix int slave_test=1;

unsigned long rtc()
{
  unsigned long rpcc = 0;
  asm volatile ("rcsr %0, 4":"=&r"(rpcc)::"memory");
  return rpcc;
}

#define NT 64
#define TEST_COUNT 32
#define CHIP_BUFF_SIZE 16
#define SERVER 0
typedef unsigned long element;

struct chip_buff
{
    element base[CHIP_BUFF_SIZE];
    volatile int head;
    volatile int tail;
};

__thread_local_fix struct chip_buff buffer[NT];
__thread_local_fix unsigned long start_time, end_time,load_time=0;
__thread_local_fix int over=0;
extern unsigned long over_addr[NT];


void init_chip_buffer()
{
    int i;
    for(i=0;i<NT;i++){
       buffer[i].head=0;
       buffer[i].tail=0;
    }
}


void clear_own_buff()
{
    struct chip_buff* self=NULL;
    int local_head=0;
    element temp_value=0;

    for(int i=0; i<NT; i++)
    {
        self=&buffer[i];
        local_head=self->head;
        if(self->tail==local_head)
        {
            i++;
            continue;
        }
        temp_value=self->base[local_head];
        self->head=(local_head+1)%CHIP_BUFF_SIZE;
        //
    }
}

__thread_local_fix int pre_index_x=0, pre_index_y=0;

element get_elem_from_NT()
{
    struct chip_buff* self=NULL;
    int local_head=0, i=0;
    element temp_value=0;

    for(i=0; i<NT; i++)
    {
        //self=&buffer[i];
        self=&buffer[(i + pre_index_x)%NT];
        local_head=self->head;
        if(self->tail==local_head)
        {
         
            continue;
        }
        temp_value=self->base[local_head];
        self->head=(local_head+1)%CHIP_BUFF_SIZE;
        pre_index_x++;
        //printf("%ld,",temp_value);
        return 1;
    }
    return 0;
}

void send_elem_to_SPE(element value, int destid)
{
    //往destid号的从核的buffer里送数据value
    struct chip_buff* self=remote_ldm(destid, (buffer[_MYID]));
    int local_tail=(self->tail+1)%CHIP_BUFF_SIZE; 
    while(self->head==local_tail)
    {
       //clear_own_buff();
    }
    self->base[self->tail]=value;
    //self->base[(local_tail-1+CHIP_BUFF_SIZE)%CHIP_BUFF_SIZE]=value;
    self->tail=local_tail;
}


void test_remote(){

    int i=0,j=0;
    
    int id=_MYID;
    unsigned long sum=0;
    
    //initilization
    init_chip_buffer();
    over_addr[id]=(unsigned long)(&over);//初始化为0
    
    //printf("-------slave_begin_%d------\n",_MYID);

    if(id!=0){  //非0号从核

        start_time=rtc();
        for(i=0;i<TEST_COUNT;i++)
        {
            send_elem_to_SPE(id, 0);  //0号从核往外发value（1-63）
            //往0号的从核的buffer里送数据id[1-63]
        }
        load_time += rtc()-start_time;
        over=1;

        //printf("id:%d,per-send_cycle:%lf\n",_MYID,(double)load_time/TEST_COUNT);

    }else{
        int upper=TEST_COUNT*(NT-1); //32*63
        //while(!over)
        unsigned long count=0;
        while(sum<upper)
        {
            sum += get_elem_from_NT();
            count++;
            if(count==100000)
            {
                printf("%ld,",sum);
                count=0;
            }
        }
        printf("\nupper=%ld, sum=%ld\n,",upper,sum);
    }
    //printf("-------slave_end_%d------\n",_MYID);

}
